#
#  Copyright 2022 The Open Islands Authors. All Rights Reserved.
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.
#
import typing

from pyoi.constant import QueueEngine
from pyoi.context.abc import MQChannelABC, MQManagerABC
from pyoi.context.types import MQArgs, FederatedPacketRouting
from pyoi.util.log_utils import getLogger

LOGGER = getLogger()

_DEFAULT_NUM_PARTITIONS = 4
_DEFAULT_MAX_MESSAGE_SIZE = 1048576


class MQ:
    @classmethod
    def create(
            cls, address, params: dict, group=None
    ) -> typing.Tuple[MQArgs, MQManagerABC]:
        mq_type = address.get("type")
        host = address.get("host")
        port = address.get("port")
        servers = address.get("servers")
        user = address.get("user")
        password = address.get("password")
        LOGGER.info(f"mq run param: {params}")
        max_message_size = params.get("max_message_size", _DEFAULT_MAX_MESSAGE_SIZE)
        params["max_message_size"] = params.get("max_message_size", _DEFAULT_MAX_MESSAGE_SIZE)
        params["num_partitions"] = params.get("num_partitions", _DEFAULT_NUM_PARTITIONS)
        LOGGER.info(f"set max message size to {max_message_size} Bytes")
        args = MQArgs(
            mq_type=mq_type,
            host=host,
            port=port,
            servers=servers,
            user=user,
            password=password,
            params=params,
        )
        manager = cls.create_manager(address=address, group=group, params=params)
        return args, manager

    @classmethod
    def create_manager(cls, address, group: str = None, params: dict = None):
        mq_type = address.get("type")
        if mq_type.upper() == QueueEngine.KAFKA.name:
            from pyoi.context.mq.kafka import MQManager
            servers = address.get("servers")
            mq_manager = MQManager(group=group, params=params, bootstrap_servers=servers)
        else:
            raise Exception(f"not support {mq_type} mq")
        return mq_manager

    @classmethod
    def get_channel(
            cls, mq_args: MQArgs, routing_info: FederatedPacketRouting = None
    ) -> MQChannelABC:
        if mq_args.mq_type.upper() == QueueEngine.KAFKA.name:
            from pyoi.context.mq.kafka import MQChannel
            return MQChannel(routing_info=routing_info, params=mq_args.params, bootstrap_servers=mq_args.servers)
        else:
            raise Exception(f"get channel not support {mq_args.mq_type} mq")
